﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

/*
 * TH07 Groep 10
 * ----------------------------------------------------------------------------------
 * Versie   Door        Commentaar
 * 0.1      Mike        Opzet en programmeer werk
 * 0.2      Erwin       Verplaatst naar Algorithms, 
 *                      aangepast om als reference te gebruiken
 */

namespace Algorithms_10.Filters
{
    /// <summary>
    /// Klasse die het algoritme bevat voor het runnen van een median filter
    /// </summary>
    public class Median
    {
        public static Bitmap RunAlgorithm(Bitmap sourceImage)
        {
            Bitmap InputImage = new Bitmap(sourceImage);

            BitmapData IData = InputImage.LockBits(
           new Rectangle(0, 0, InputImage.Width, InputImage.Height),
           ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            ///////////////////////////////////////////////////////////
            unsafe
            {
                // Declare an array to hold the bytes of the bitmap.
                int bytes = Math.Abs(IData.Stride) * IData.Height;
                byte[] rgbValues = new byte[bytes];
                int pixelsize = 3;
                // Copy the RGB values into the array.
                System.Runtime.InteropServices.Marshal.Copy(IData.Scan0, rgbValues, 0, bytes);
                for (int y = 5; y < InputImage.Height - 5; y++)
                {
                    //get the data from the original image
                    byte* row = (byte*)IData.Scan0 + (y * (IData.Stride));


                    for (int x = 5 * pixelsize; x < IData.Stride - 5 * pixelsize; x += pixelsize)
                    {
                        byte[] pixels = new byte[121];
                        int pixIndex = 0;
                        for (int yy = -5; yy < 6; yy++)
                        {

                            for (int xx = -5; xx < 6; xx++)
                            {
                                pixels[pixIndex] = (rgbValues[x + ((y - yy) * (IData.Stride)) - xx * pixelsize]);
                                pixIndex++;

                            }
                        }

                        byte[] histogram = new byte[256];

                        for (int i = 0; i < pixels.Length; i++)
                        {
                            histogram[pixels[i]]++;
                        }

                        int value = 0;
                        byte temp = 0;
                        while (true)
                        {
                            value += histogram[temp];
                            if (value >= 60)
                            {
                                row[x] = row[x + 1] = row[x + 2] = temp;
                                break;
                            }

                            temp++;
                        }
                    }
                }
            }
            ///////////////////////////////////////////////////////////               

            //unlock
            InputImage.UnlockBits(IData);

            return InputImage;
        }
    }
}
